﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using ProgramMain.Database;
using ProgramMain.Database.SimpleOpticNetDBTableAdapters;
using ProgramMain.Google;

namespace ProgramMain.Layers
{
    public class MeasureTreeNode : IGoogleTreeNode
    {
        private SimpleOpticNetDB.MeasuresRow _Row;

        public GoogleTreeTypes NodeType
        {
            get { return GoogleTreeTypes.Line; }
        }

        public Coordinate Coordinate
        {
            get { throw new NotImplementedException(); }
        }

        public CoordinateRectangle Rectangle
        {
            get
            {
                return new CoordinateRectangle(
                    _Row.Longitude1,
                    _Row.Latitude1,
                    _Row.Longitude2,
                    _Row.Latitude2);
            }
        }

        public int RowID
        {
            get { return _Row.ID; }
        }

        internal MeasureTreeNode(SimpleOpticNetDB.MeasuresRow row)
        {
            _Row = row;    
        }

        public DataRow Row
        {
            get { return _Row; }
        }
    }

    public class MeasureTree : GoogleTree<MeasureTreeNode>
    {
        public SimpleOpticNetDB.MeasuresDataTable MeasureTreeDBRows { get; private set; }

        public double Ruler { get; private set; }
        private Coordinate LastPoint = null;

        public MeasureTree()
            : base(LevelPowerTypes.Micro, LevelPowerTypes.Extra, LevelPowerTypes.Medium, LevelPowerTypes.Low)
        {
            MeasureTreeDBRows = new SimpleOpticNetDB.MeasuresDataTable();
            ClearMeasureData();
        }

        public void ClearMeasureData()
        {
            Clear();
            
            MeasureTreeDBRows.Clear();
            
            LastPoint = null;
            Ruler = 0;
        }

        public void Reload()
        {
            Clear();

            Parallel.ForEach(MeasureTreeDBRows.Cast<SimpleOpticNetDB.MeasuresRow>(), Insert);
        }
        
        public void Insert(SimpleOpticNetDB.MeasuresRow row)
        {
            base.Insert(new MeasureTreeNode(row));
        }

        public void Delete(SimpleOpticNetDB.MeasuresRow row)
        {
            base.Delete(new MeasureTreeNode(row));
        }

        public void EditMeasure(Coordinate oldCoordinate, Coordinate coordinate)
         {
             for (int i = 0; i<MeasureTreeDBRows.Count; i++)
             {
                 bool f = false;
                 SimpleOpticNetDB.MeasuresRow row = MeasureTreeDBRows[i];
                 if (row.Latitude1 == (decimal)oldCoordinate.Latitude && row.Longitude1 == (decimal)oldCoordinate.Longitude)
                 {
                     row.Latitude1 = (decimal)coordinate.Latitude;
                     row.Longitude1 = (decimal)coordinate.Longitude;
                     f = true;
                 }

                 if (row.Latitude2 == (decimal)oldCoordinate.Latitude && row.Longitude2 == (decimal)oldCoordinate.Longitude)
                 {
                     row.Latitude2 = (decimal)coordinate.Latitude;
                     row.Longitude2 = (decimal)coordinate.Longitude;
                     f = true;
                 }
                 if(f)
                 {
                     Coordinate c1 = new Coordinate(row.Longitude1, row.Latitude1);
                     Coordinate c2 = new Coordinate(row.Longitude2, row.Latitude2);
                     row.Length = c1.Distance(c2);

                 }
             }
            MeasureTreeDBRows.EndInit();
         }

        public void AddMeasure(Coordinate point)
        {
            if (MeasureTreeDBRows == null) return;
            if (LastPoint == null)
            {
                LastPoint = (Coordinate)point.Clone();
            }
            else
            {
                Ruler += LastPoint.Distance(point);
                SimpleOpticNetDB.MeasuresRow newRow = MeasureTreeDBRows.NewMeasuresRow();
                newRow.Longitude1 = (decimal)LastPoint.Longitude;
                newRow.Latitude1 = (decimal)LastPoint.Latitude;
                newRow.Longitude2 = (decimal)point.Longitude;
                newRow.Latitude2 = (decimal)point.Latitude;
                newRow.Length = Ruler;

                MeasureTreeDBRows.Rows.Add(newRow);

                Insert(newRow);

                LastPoint = (Coordinate)point.Clone();
            }
        }

        public SimpleOpticNetDB.MeasuresRow FindMeasure(int ID)
        {
            return this.MeasureTreeDBRows.FindByID( ID);
            
        }
    }
}
